package br.com.commons.utility.datatable.handler;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import br.com.commons.utility.datatable.DataTable;
import br.com.commons.utility.datatable.builder.DataTableBuilder;

import com.google.gson.Gson;

public abstract class DataTableHandler {

	protected DataTable dataTable;
	protected String[] columns;
	
	public String execute(Map<String, Object> dados){		
		columns = getColumns();
		DataTableBuilder dataTableBuilder = new DataTableBuilder(dados);
		setDataTable(dataTableBuilder);
		return new Gson().toJson(dataTable);
	}
	
	private void setDataTable(DataTableBuilder dataTableBuilder){
		dataTable = dataTableBuilder.getDataTable();		
		dataTable.setAaData(getRegisters());	
		Long numberRegister = getTotalNumberOfRegister(getSearchColumns(), dataTable.getSearchValue());
		dataTable.setiTotalDisplayRecords(numberRegister);
		dataTable.setiTotalRecords(numberRegister);
	}
	
	private List<String[]> getRegisters(){
		List<?> listaObject = getListObjects(getSearchColumns(), dataTable.getSearchValue(), getOrderColumn(), dataTable.getOrderDirection(), dataTable.getFirstPosition(), dataTable.getNumberOfRecords());		
		return getRegistersFormated(listaObject);
	}
	
	private List<String> getSearchColumns() {
		List<String> listColumns = new ArrayList<String>();
		for (int i = 0; i < columns.length; i++) {
			if(dataTable.getSearchColumns()[i]){
				listColumns.add(columns[i]);
			}
		}
		return listColumns;
	}
	
	private String getOrderColumn() {
		return columns[dataTable.getOrderColumn()];
	}

	private List<String[]> getRegistersFormated(List<?> listaObject) {
		List<String[]> listRegisterFormated = new ArrayList<String[]>();	
		for (int i = 0; i < listaObject.size(); i++) {
			listRegisterFormated.add(getObject(listaObject.get(i)));
		}
		return listRegisterFormated;
	}

	protected abstract String[] getColumns();
	protected abstract List<?> getListObjects(List<String> searchColumns, String searchValue, String orderColumn, String orderDirection, int firstPosition, int numberOfRecords);
	protected abstract String[] getObject(Object object);
	protected abstract Long getTotalNumberOfRegister(List<String> searchColumns, String searchValue);
	
}
